//
//  TGMBaseModel.h
//  TravelGuideMdd
//
//  Created by Song Xiaofeng on 13-8-6.
//  Copyright (c) 2013年 mafengwo.com. All rights reserved.
//

#import "sdk.h"

@class BaseItem;

#define  kModelParam_Str_DataId @"data_id"



@interface TGMBaseModelActionData : NSObject

/**
 *  @see @selector(dataWithApi:params:dataId:) which dataId is `mfwDefaultDataId`
 *
 *  @param aApiUrl
 *  @param aParams
 *
 *  @return
 */
+ (instancetype)dataWithApi:(NSString*)aApiUrl params:(NSDictionary*)aParams;

/**
 *  see @selector(dataWithApi:httpMethod:params:dataId:) which httpMethod is POST
 *
 *  @param aApiUrl
 *  @param aParams
 *  @param dataIdBlock
 *
 *  @return
 */
+ (instancetype)dataWithApi:(NSString*)aApiUrl
                     params:(NSDictionary*)aParams
                     dataId:(NSString*(^)(NSString *dataId))dataIdBlock;

+ (instancetype)dataWithApi:(NSString *)aApiUrl httpMethod:(RequestHttpMethod)httpMethod params:(NSDictionary *)aParams;


/**
 *  factory function
 *
 *  @param aApiUrl    full api url path
 *  @param httpMethod http method
 *  @param aParams    origin parameters (usually without urlencode)
 *  @param NSString   dataId generate block
 *
 *  @return
 */
+ (instancetype)dataWithApi:(NSString *)aApiUrl
                 httpMethod:(RequestHttpMethod)httpMethod
                     params:(NSDictionary *)aParams
                     dataId:(NSString *(^)(NSString *))dataIdBlock;

@property (nonatomic, readonly) NSString        *dataId;
@property (nonatomic, readonly) NSDictionary    *params;
@property (nonatomic, readonly) NSString        *apiUrl;

@property (nonatomic, copy)     NSString        *pageStartKey;
@property (nonatomic, copy)     NSString        *pageLengthKey;
@property (nonatomic, assign)   NSUInteger       pageLength;
@property(nonatomic, assign)    RequestHttpMethod httpMethod;

@end

@interface TGMBaseModel : MFWServiceModel
{
    /**
     *	key -> $dataId, value -> NSArray which contents parsed modelItems
     */
    NSMutableDictionary *_parsedModelItemDataDic;
}

- (MFWTask*)requestRefresh:(TGMBaseModelActionData*)param;
- (MFWTask*)requestGetMore:(TGMBaseModelActionData*)param;

/**
 *	class type of model item
 *
 *	@param	dataId	
 *
 *	@return	class type which is sub-class of BaseItem
 */
- (Class)classOfModelItemForDataId:(NSString*)dataId;

/**
 * sub-class should override to implement its fuctional
 *
 *  @param dataId
 *
 *	@return	cache key of model value in cache-db
 */
- (NSString*)keyOfPersistentCacheForDataId:(NSString*)dataId;

/**
 *	get pasrsed Model Item array
 *
 *	@param	dataId
 *
 *	@return pasrsed Model Item array
 */
- (NSArray*)listModelItemForDataId:(NSString*)dataId;

/**
 *	本地列表数据的总数
 *
 *	@param	dataId	dataId
 *
 *	@return 本地列表数据的总数
 */
- (NSUInteger)countOfReceivedListDataForDataId:(NSString*)dataId;

///**
// *	@see [self listModelItemForDataId:@"0"]
// *
// *	@return	
// */
//- (NSArray*)listModelItem;

/**
 *  append an item to the tail of list array

 *  会更新缓存
 *
 *  @param item model item
 *  @dataId
 */
- (BOOL)appendModelItem:(BaseItem*)item forDataId:(NSString*)dataId;

/**
 *  insert an item to the ahead of list array

 *  会更新缓存
 *
 *  @param item  item model item
 *  @param dataId dataId
 *
 *  @return 是否成功
 */
- (BOOL)insertAheadModelItem:(BaseItem*)item forDataId:(NSString*)dataId;

/**
 *  删除列表中的一条或多条

 *  会更新缓存
 *
 *  @param predicate The block to apply to elements in the array. 通过该block测试的items将被删除
 *                   The block takes three arguments:
 *                   obj
 *                   The element in the array.
 *                   idx
 *                   The index of the element in the array.
 *                   stop
 *                   A reference to a Boolean value. The block can set the value to YES to stop further processing of the array. The stop argument is an out-only argument. You should only ever set this Boolean to YES within the Block.
 * @param dataId dataId
 *
 *  @return 成功命中删除的条数
 */
- (NSUInteger)deleteItemForDataId:(NSString *)dataId usingPassingTest:(BOOL(^)(id obj, NSUInteger idx, BOOL *stop))predicate;

/**
 *	model中的数据是否需要刷新

 *  进页面自动刷新时需要判断该方法
 *
 *	@param	dataId	dataId
 *
 *	@return	
 */
- (BOOL)needRefreshForDataId:(NSString*)dataId;

/**
 *  the key of has more, default value is "has_more"
 *
 *  @param dataId
 *
 *  @return key
 */
- (NSString*)optHasMoreKeyForDataId:(NSString*)dataId;

/**
 *	是否可以获取更多，只有当数据取完或者当前数据没有成功刷新过时返回NO，
 *
 *	@param	dataId	dataId
 *
 *	@return
 */
- (BOOL)canGetMoreForDataId:(NSString*)dataId;

/**
 *  缓存的持续时间，如果小于0则永远缓存，如果大于0，且缓存时间大于该值，则会废弃掉该缓存，
 *  并从缓存中移除。
 *  [注] 目前（2014-10-16）该机制只在加载缓存时检查
 *
 *  @return 最大缓存时间，默认返回-1
 */
- (NSTimeInterval)maxCacheAge;

/**
 *  更新缓存，将dataId对应的数据重新写入缓存数据库
 *
 *  @param dataId
 */
- (void)synchronizeCacheForDataId:(NSString*)dataId;

+ (NSArray*)parseModelItemArrayFromJsonArray:(MFWJson*)jsonArray itamClass:(Class)clazz;
@end

@interface MFWHttpTask(TGMBaseModelHelper)
- (NSArray*)relativeListModelItemForDataId;
- (BOOL)relativeModelNeedRefresh;
- (BOOL)relativeModelCanGetMore;
@end

@interface TGMBaseModel(launchDateStamp)

@property (nonatomic, readonly) NSDate *launchDateStamp;
+ (NSDate*)launchDateStamp;

@end





